class LHSConfig:
    """配置参数类（优化随机性控制）"""
    SAMPLE_SIZE = 1000  # 默认样本量
    PLOT_SIZE = (18, 12)  # 图形尺寸
    DPI = 150  # 图形分辨率
    SEED = 42  # 全局随机种子（仅初始化时使用）
    OUTPUT_PRECISION = 2  # 输出小数位数
    # 新增：泊松过程参数（与理论一致）
    CRANE_FAILURE_RATE = 1 / 3000  # 每小时故障率
    MTBF = 1 / CRANE_FAILURE_RATE
    TOTAL_HOURS = 153 * 10  # 总时长（153天，每天10小时）
    SIGNIFICANCE_LEVEL = 0.05


import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import poisson, kstest, kstwobign
from collections import Counter

# -------------------------------
# 参数设置
# -------------------------------
MTBF = 3000  # 平均无故障时间（小时）
T = 1530     # 采样时间段（小时）
lambda_rate = 1 / MTBF   # 故障率 (次/小时)
mu = lambda_rate * T     # 区间内期望故障次数
SAMPLE_SIZE = 1000         # 总采样次数

np.random.seed(42)  # 固定随机种子确保结果可复现

# -------------------------------
# 模拟采样过程
# -------------------------------
failure_counts_of_all_samplings_list = []   # 存储每次采样的故障次数
sorted_failure_occurrence_times_of_all_samplings_list = []    # 存储所有故障发生时刻
failure_occurrence_times_of_every_samplings_list_of_list = []
# N_SAMPLES次采样，生成故障次数和故障发生时刻
for _ in range(SAMPLE_SIZE):
    # 步骤1：根据泊松分布采样故障次数failure_count_of_one_sampling
    failure_count_of_one_sampling = np.random.poisson(mu)
    failure_counts_of_all_samplings_list.append(failure_count_of_one_sampling)

    # 步骤2：若存在故障，从均匀分布采样故障时刻
    if failure_count_of_one_sampling > 0:
        times = np.random.uniform(0, T, size=failure_count_of_one_sampling)
        # 需要保留这个times列表，以便仿真时使用
        failure_occurrence_times_of_every_samplings_list_of_list.append(times)
        times.sort()  # 对时间排序，符合实际发生顺序
        sorted_failure_occurrence_times_of_all_samplings_list.extend(times)
    else:
        # 需要生成一个空列表，以便仿真时使用
        failure_occurrence_times_of_every_samplings_list_of_list.append([])

# -------------------------------
# 统计分析
# -------------------------------
counts_freq = Counter(failure_counts_of_all_samplings_list)
print("Distribution of failure counts:", counts_freq)

# 计算理论分布
max_count = max(counts_freq.keys()) if counts_freq else 0
k_values = np.arange(0, max_count + 1)
theoretical_probs = poisson.pmf(k_values, mu)
theoretical_counts = theoretical_probs * SAMPLE_SIZE

# -------------------------------
# 分布检验（验证采样是否符合理论）
# -------------------------------
if len(sorted_failure_occurrence_times_of_all_samplings_list) > 0:
    u_values = np.array(sorted_failure_occurrence_times_of_all_samplings_list) / T  # 归一化到[0,1]区间，用于均匀性检验
    ks_stat, ks_p = kstest(u_values, 'uniform')
    ks_stat = round(ks_stat,4)
    ks_p = round(ks_p,4)
    print(f"KS test (uniformity of failure times): D = {ks_stat:.4f}, p-value = {ks_p:.4f}")

# -------------------------------
# 可视化 - 故障次数分布对比
# -------------------------------
plt.figure(figsize=(12, 5))

# 左图：故障次数的理论与采样分布
plt.subplot(1, 2, 1)

# 采样分布（实证分布）
plt.bar(k_values, [counts_freq.get(k, 0) for k in k_values],
        alpha=0.6, color='blue', label='Empirical distribution')

# 理论泊松分布(默认plot的legend在前)
plt.plot(k_values, theoretical_counts, 'ro-', linewidth=2,
         label=f'Theoretical Poisson (λ={mu:.2f})')

plt.xlabel('Number of failures')
plt.ylabel('Frequency')
plt.title('Comparison of failure count distributions')

plt.legend()

# -------------------------------
# 可视化 - 故障时刻分布对比
# -------------------------------
# 右图：故障时刻的理论与采样分布
plt.subplot(1, 2, 2)
# 理论均匀分布密度
plt.hlines(1/T, 0, T, colors='r', linewidth=2,
           label='Theoretical uniform distribution')

# 采样时刻分布（实证分布）
plt.hist(sorted_failure_occurrence_times_of_all_samplings_list, bins=20, density=True, alpha=0.6, color='blue',
         label='Empirical distribution')


if len(sorted_failure_occurrence_times_of_all_samplings_list) > 0:
    d_critical = round(kstwobign.isf(0.05), 4)
    ks_stat_comparison_str = f"ks_stat({ks_stat})>d_critical({d_critical})" if ks_stat > d_critical else f"ks_stat({ks_stat})<d_critical({d_critical})"
    p_value_comparison_str = f"ks_p({ks_p})>SIG_LEVEL({LHSConfig.SIGNIFICANCE_LEVEL})" if ks_p > LHSConfig.SIGNIFICANCE_LEVEL else f"ks_p({ks_p})<SIG_LEVEL({LHSConfig.SIGNIFICANCE_LEVEL})"

    plt.text(0.05, 0.05, f"KS test:\n{ks_stat_comparison_str}\n{p_value_comparison_str}",
             transform=plt.gca().transAxes, ha='left', va='bottom',
             bbox=dict(facecolor='white', alpha=0.8))


plt.xlabel('Failure time (hours)')
plt.ylabel('Probability density')
plt.title('Comparison of failure time distributions')
plt.legend()

plt.tight_layout()
plt.show()
